Skip to content

Fix paragraph indentation issue - #508

Merged
kepano merged 1 commit into
obsidianmd:masterfrom
Xheldon:notion-api-492
Aug 5, 2026
Merged

Fix paragraph indentation issue#508
kepano merged 1 commit into
obsidianmd:masterfrom
Xheldon:notion-api-492

Conversation

@Xheldon

@Xheldon Xheldon commented Feb 27, 2026

Copy link
Copy Markdown
Contributor

Fix #492

Indentation elements below a paragraph were previously ignored; now they are correctly imported as child elements of the paragraph and indented.

But note that some Markdown elements do not support nesting, so you may encounter expected layout issues. For example, if a Paragraph in Notion has a Heading element as a child, when it’s imported into Obsidian it won’t be properly indented and rendered as a Heading; it will just appear as an indented "#" followed by the text content of heading.

@tgrosinger

tgrosinger commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

I'm not sure that I understand this change. In obsidian if you indent a block of text, it turns it into a code block. That's not what we want when imported indented text from Notion, right?

@Xheldon

Xheldon commented Mar 16, 2026

Copy link
Copy Markdown
Contributor Author

@tgrosinger Are you referring to indentation as a Tab? Currently, the indentation of elements under a paragraph actually adds four spaces, as shown in the figure(ignore the content, i modify it after imported):

Notion content:
image

Obsidian Import it:
image

But it's true that indentation can cause many unexpected problems, such as list nesting. Unordered lists seem fine, but ordered lists don't appear to nest correctly after indentation.

Is this expected?

@Xheldon

Xheldon commented Mar 16, 2026

Copy link
Copy Markdown
Contributor Author

Also, I noticed that whether I use a Tab or four spaces for indentation, it doesn't turn into a code block. Am I missing something, or have I set something incorrectly?

@tianjiaoding

Copy link
Copy Markdown

Thank you for the efforts! I think the issue that the PR addresses is: currently, when there are indented content under a paragraph in Notion, the imported Obsidian markdown ignores the indented content (not only just the indentation). Perhaps it is up to debate how these content should be properly indented in Obsidian, but i think keeping these content is crucial.

@kepano
kepano merged commit 7756bb5 into obsidianmd:master Aug 5, 2026
kepano added a commit that referenced this pull request Aug 6, 2026
…covery testable (#599)

* Notion API: Cover indented paragraphs in the page fixture

A paragraph with has_children was not represented, so nothing caught the
children being dropped (#492). Two shapes are recorded: a parent with its
own text, and the empty parent Notion writes when a block is indented
under a blank line.

Checked against the bug: with #508 reverted the recording loses both
child lines and keeps only the parent, which is what users saw.

* Notion: Cover a database row's properties

The conversion turns a page's property table into frontmatter, reading it
through tbody.rows and tr.cells. linkedom implements neither, so the path
threw before it converted anything and no test could reach it - and no
committed export carries a property table to reach it with.

The shim supplies both, on Element because linkedom gives every element
the plain HTMLElement prototype. Measured rather than assumed: no
recorded output moves, and an Evernote table - the one place turndown's
GFM rules read .rows - converts byte for byte as before.

The page is hand-written to the export's shape, which it says, and a real
export with a database should replace it. Checked against the bug: with
#577 reverted the recording loses Price (BRL), Price (USD) and Discount
entirely, which is what #407 reported.

* Notion API: Let the live check find a page that has blocks

Without NOTION_PAGE_ID it read whichever page search returned first and
asserted that page had blocks. In a workspace whose first result is a
database row - which keeps its content in properties and has no blocks at
all - the check failed on the workspace rather than on the API, which is
the one thing it is not meant to report.

It now reads candidates until one has blocks, and says so plainly if none
does. Checked against a real workspace: it passes there, so the shapes
example-page.json is written to are the ones the API still returns.

* Notion API: Move page discovery off the importer

Turning a search response into the tree the picker draws needs nothing
from the vault or the network, but it sat on the importer where no test
could reach it - so diagnosing a report of a missing page meant
reimplementing the filtering in a scratch script and trusting that the
copy agreed with the original.

Moved as it stands. The two filter phases, extractItemTitle,
extractParentId and buildTree are the same code with this. instead of a
receiver, and NotionParent and NotionTreeNode move with them.

Checked against a real workspace of 1123 search results: same 1064 items
and same 7 roots, with the same children under each.

* Notion API: Record which pages the picker offers

The search response is the one input that decides whether a page can be
imported at all, and every report of a missing one - #590, #512 - is a
claim about what this drops. Nothing recorded what it keeps.

The fixture carries each object and parent combination seen in a real
workspace, including the two the reports turn on: a database that is
itself a top-level page, and one inline in a block. Recorded output is
the tree as an outline, so a page that stops being offered is a line that
moves.

A top-level database is offered today, which is what #590 says it is not.
The reporter's integration was connected to the database alone rather
than to the workspace, and that is the part still to reproduce.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Content missing for indented text blocks during Notion API import

4 participants